package com.example.shw

import android.Manifest
import android.annotation.SuppressLint
import android.content.Context
import android.content.pm.PackageManager
import android.graphics.Canvas
import android.graphics.Color
import android.graphics.Paint
import android.graphics.Rect
import android.media.AudioManager
import android.media.MediaPlayer
import android.media.audiofx.BassBoost
import android.media.audiofx.Equalizer
import android.media.audiofx.PresetReverb
import android.media.audiofx.Visualizer
import android.os.Bundle
import android.support.v7.app.AppCompatActivity
import android.util.Log
import android.view.Gravity
import android.view.MotionEvent
import android.view.View
import android.view.ViewGroup
import android.widget.*
import kotlinx.android.synthetic.main.activity_audio.view.*

class VisualizerMusicActivity : AppCompatActivity(){
    //定义播放声音的MediaPlayer
    private var mPlayer: MediaPlayer? = null
    //定义系统的示波器
    private lateinit var mVisualizer: Visualizer
    //定义系统的均衡器
    private lateinit var mEqualizer: Equalizer
    //定义系统的重低音控制器
    private lateinit var mBass: BassBoost
    //定义系统的预设音场控制器
    private lateinit var mPresetReverb: PresetReverb

    private lateinit var layout: LinearLayout
    private val reverbNames = ArrayList<Short>()
    private val reverbVals = ArrayList<String>()
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        //设置控制音乐声音
        volumeControlStream = AudioManager.STREAM_MUSIC
        layout = LinearLayout(this)
        layout.orientation = LinearLayout.VERTICAL
        setContentView(layout)
        requestPermissions(arrayOf(Manifest.permission.RECORD_AUDIO), 0x123)
    }

    override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>, grantResults: IntArray) {
        if (requestCode == 0x123 && grantResults != null
            && grantResults[0] == PackageManager.PERMISSION_GRANTED)
        {
            mPlayer = MediaPlayer.create(this, R.raw.imhappy)
            //TODO
            //1.初始化示波器
            setupVisulizer()
            //2.初始化均衡控制器
            setupEqualizer()
            //3.初始化重低音控制器
            setupBassBoost()
            //4.初始化预设音场控制器
            setupPreseReverb()

            mPlayer?.start()
        }
    }

    private fun setupVisulizer(){
        val mVisualizerView = MyVisualizerView(this)
        mVisualizerView.layoutParams = ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
            (120f * resources.displayMetrics.density).toInt())
        layout.addView(mVisualizerView)
        //以MediaPlayer的AudioSessionId创建Visualizer
        mVisualizer = Visualizer(mPlayer!!.audioSessionId)
        mVisualizer.captureSize = Visualizer.getCaptureSizeRange()[1]
        mVisualizer.setDataCaptureListener(object : Visualizer.OnDataCaptureListener{
            override fun onWaveFormDataCapture(visualizer: Visualizer?, waveform: ByteArray, samplingRate: Int) {
                //用waveform波形数据更新mVisualizerView
                mVisualizerView.updateVisualizer(waveform)
            }

            override fun onFftDataCapture(visualizer: Visualizer?, fft: ByteArray?, samplingRate: Int) {
            }

        }, Visualizer.getMaxCaptureRate() / 2, true, false)
        mVisualizer.enabled = true
    }

    //初始化均衡控制器
    @SuppressLint("SetTextI18n")
    private fun setupEqualizer(){
        //以MediaPlayer的AudioSessionId创建Equalizer
        mEqualizer = Equalizer(0, mPlayer!!.audioSessionId)
        mEqualizer.enabled = true
        val eqTitle = TextView(this)
        eqTitle.text = "均衡器："
        layout.addView(eqTitle)
        //获取均衡器支持的最小值和最大值
        val minEQLevel = mEqualizer.bandLevelRange[0]
        val maxEQLevel = mEqualizer.bandLevelRange[1]
        //获取均衡器支持的所有频率
        val brands = mEqualizer.numberOfBands
        for (i in 0 until brands){
            val eqText = TextView(this)
            //显示频率
            eqText.layoutParams = ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
                ViewGroup.LayoutParams.WRAP_CONTENT)
            eqText.gravity = Gravity.CENTER_HORIZONTAL
            eqText.text = (mEqualizer.getCenterFreq(i.toShort()) / 1000).toString() + "Hz"
            layout.addView(eqText)

            val tmpLayout = LinearLayout(this)
            tmpLayout.orientation = LinearLayout.HORIZONTAL
            val minDbTextView = TextView(this)
            minDbTextView.layoutParams = ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,
                ViewGroup.LayoutParams.WRAP_CONTENT)
            minDbTextView.text = (minEQLevel / 100).toString() + " dB"
            val maxDbTextView = TextView(this)
            maxDbTextView.layoutParams = ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,
                ViewGroup.LayoutParams.WRAP_CONTENT)
            maxDbTextView.text = (maxEQLevel / 100).toString() + " dB"

            val layoutParams = LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
                ViewGroup.LayoutParams.WRAP_CONTENT)
            layoutParams.weight = 1f
            val bar = SeekBar(this)
            bar.layoutParams = layoutParams
            bar.max = maxEQLevel - minEQLevel
            bar.progress = mEqualizer.getBandLevel(i.toShort()).toInt()
            bar.setOnSeekBarChangeListener(object : SeekBar.OnSeekBarChangeListener{
                override fun onStopTrackingTouch(seekBar: SeekBar?) {
                }

                override fun onStartTrackingTouch(seekBar: SeekBar?) {
                }

                override fun onProgressChanged(seekBar: SeekBar?, progress: Int, fromUser: Boolean) {
                    mEqualizer.setBandLevel(i.toShort(),(progress + minEQLevel).toShort())
                }

            })
            tmpLayout.addView(minDbTextView)
            tmpLayout.addView(bar)
            tmpLayout.addView(maxDbTextView)
            layout.addView(tmpLayout)
        }
    }

    //初始化重低音控制器
    private fun setupBassBoost(){
        //以MediaPlayer的AudioSessionId创建BassBoost
        mBass = BassBoost(0, mPlayer!!.audioSessionId)
        //设置启用重低音效果
        mBass.enabled = true
        val bbTitle = TextView(this)
        bbTitle.text = "重低音："
        layout.addView(bbTitle)
        val bar = SeekBar(this)
        //重低音的范围为 0 ~ 1000
        bar.max = 1000
        bar.progress = 0

        bar.setOnSeekBarChangeListener(object : SeekBar.OnSeekBarChangeListener{
            override fun onStopTrackingTouch(seekBar: SeekBar?) {
            }

            override fun onStartTrackingTouch(seekBar: SeekBar?) {
            }

            override fun onProgressChanged(seekBar: SeekBar?, progress: Int, fromUser: Boolean) {
                mBass.setStrength(progress.toShort())
            }

        })
        layout.addView(bar)
    }
    //初始化预设音场控制器
    private fun setupPreseReverb(){
        //以MediaPlayer的AudioSessionId创建PresetReverb
        mPresetReverb = PresetReverb(0, mPlayer!!.audioSessionId)
        mPresetReverb.enabled = true
        val prTitle = TextView(this)
        prTitle.text = "音场"
        layout.addView(prTitle)
        //mEqualizer.numberOfPresets为10，设置的时候低版本会有问题
        for (i in 0 until 7){
            reverbNames.add(i.toShort())
            reverbVals.add(mEqualizer.getPresetName(i.toShort()))
        }
        Log.d("12345",reverbNames.toString())
        Log.d("12345",reverbVals.toString())
        //使用Spinner作为音场选择工具
        val sp = Spinner(this)
        sp.adapter = ArrayAdapter(this@VisualizerMusicActivity, android.R.layout.simple_spinner_item,
            reverbVals)
        sp.onItemSelectedListener = object : AdapterView.OnItemSelectedListener{
            override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) {
                //设置音场
                Log.d("12345", reverbNames[position].toString())
                mPresetReverb.preset = reverbNames[position]
            }

            override fun onNothingSelected(parent: AdapterView<*>?) {
            }
        }
        layout.addView(sp)
    }

    override fun onPause() {
        super.onPause()
        if (isFinishing && mPlayer != null){
            //释放所有对象
            mVisualizer.release()
            mEqualizer.release()
            mPresetReverb.release()
            mBass.release()
            mPlayer!!.release()
            mPlayer = null
        }
    }

    private class MyVisualizerView(context: Context) : View(context){
        //bytes数组保存了波形抽样点的值
        private var bytes: ByteArray? = null
        private var points: FloatArray? = null
        private val paint:Paint = Paint()
        private val rect: Rect = Rect()
        private var type: Byte = 0
        fun updateVisualizer(ftt: ByteArray)
        {
            bytes = ftt
            invalidate()
        }

        override fun onTouchEvent(event: MotionEvent): Boolean {
            //当用户触碰该组件的之后，切换波形类型
            if (event.action != MotionEvent.ACTION_DOWN) return false

            type++

            if (type >= 3) type = 0

            return true
        }
        init {
            paint.strokeWidth = 1f
            paint.isAntiAlias = true
            paint.color = Color.GREEN
            paint.style = Paint.Style.FILL
        }

        override fun onDraw(canvas: Canvas) {
            super.onDraw(canvas)
            if (bytes == null) return

            canvas.drawColor(Color.WHITE)
            //使用rect对象记录该组件的宽度和高度
            rect.set(0, 0, width, height)
            when (type)
            {
                //绘制块状的波形图
                0.toByte() -> for (i in 0 until bytes!!.size - 1)
                {
                    val left = (width * i / (bytes!!.size - 1).toFloat())
                    val top = rect.height() - (bytes!![i + 1] + 128).toFloat()
                    val right = left + 1
                    val bottom = rect.height().toFloat()
                    canvas.drawRect(left, top, right, bottom, paint)
                }
                //绘制柱状的波形图
                1.toByte() -> kotlin.run {
                    var i = 0
                    while (i < bytes!!.size - 1)
                    {
                        val left = rect.width() * i / (bytes!!.size - 1)
                        val top = rect.height() - (bytes!![i + 1] + 128).toByte() * rect.height() / 128
                        val bottom = rect.height()
                        val right = left + 6
                        canvas.drawRect(left.toFloat(), top.toFloat(), right.toFloat(), bottom.toFloat(), paint)
                        i += 18
                    }
                }
                //绘制曲线波形图
                2.toByte() -> {
                    //如果points数组还没有初始化
                    if(points == null || points!!.size < bytes!!.size * 4)
                    {
                        points = FloatArray(bytes!!.size * 4)
                    }
                    for (i in 0 until bytes!!.size - 1)
                    {
                        points?.set(i * 4, rect.width() * i / (bytes!!.size - 1).toFloat())

                        points?.set(i * 4 + 1, rect.height() / 2 + (bytes!![i] + 128).toByte() * 128 / (rect.height() / 2).toFloat())

                        points?.set(i * 4 + 2, rect.width() * (i + 1) / (bytes!!.size - 1).toFloat())

                        points?.set(i * 4 + 3, rect.height() / 2 + (bytes!![i + 1] + 128).toByte() * 128 / (rect.height() / 2).toFloat())
                    }
                    canvas.drawLines(points, paint)
                }
            }
        }
    }
}